﻿#if NETFX || NETCORE

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace Apewer.Surface
{

    /// <summary></summary>
    internal class BlockCombo : BaseControl
    {

        private bool _delemiter = false;
        // private bool _lonely = false;
        private bool _statehover = false, _statefocus = false;

        private List<string> _value = new List<string>();
        private List<string> _alias = new List<string>();
        private List<Color> _color = new List<Color>();

        // private Panel _body = new Panel();
        private Panel _left = new Panel();
        // private Panel _middle = new Panel();
        private Panel _right = new Panel();
        private BlockLabel _label = new BlockLabel();
        private ComboBox _input = new ComboBox();

        #region this

        private void VarInit()
        {
            _label.Text = "Caption";
            _input.Text = Name;

            for (int i = 1; i <= 12; i++)
            {
                //_input.Items.Add(i.ToString());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public BlockCombo()
        {
            this.Size = new Size(300, 40);

            VarInit();

            ControlInit();
            ControlAdjust();
            EventInit();
            GoColor();
        }

        /// <summary>
        /// 
        /// </summary>
        public new void Dispose()
        {
            if (_left != null) _left.Dispose();
            if (_right != null) _right.Dispose();
            if (_label != null) _label.Dispose();
            if (_input != null) _input.Dispose();
            base.Dispose();
        }

        #endregion

        #region surface

        private void ControlInit()
        {
            Controls.Add(_left);
            Controls.Add(_right);
            _left.Controls.Add(_label);
            _right.Controls.Add(_input);

            Padding = new Padding(1);

            _left.Dock = DockStyle.Left;
            _left.Padding = new Padding(8, 0, 8, 0);
            _left.Width = 100;

            _label.Dock = DockStyle.Fill;
            _label.TextAlign = ContentAlignment.MiddleCenter;

            _right.Dock = DockStyle.Right;

            _input.Font = FormsUtility.DefaultFont;
            _input.Left = 9;
            _input.FlatStyle = FlatStyle.Flat;
            _input.DrawMode = DrawMode.OwnerDrawVariable;
            _input.DropDownStyle = ComboBoxStyle.DropDown;
            _input.ItemHeight = 20;
            _input.BackColor = FormsUtility.GraceWall;
        }

        private void ControlAdjust()
        {
            var vfontoffset = FormsUtility.MsyhExist ? 0 : 2;

            _right.Width = Width - Padding.Left - Padding.Right - _left.Width - (_delemiter ? 1 : 0);

            _input.Width = _right.Width - 9 - 4;
            _input.Top = (_right.Height - 22) / 2;
        }

        private void GoColor()
        {
            if (_statefocus)
            {
                this.BackColor = _focusborder;
                _left.BackColor = _focusleft;
                _left.ForeColor = _focuscaption;
                _right.BackColor = _focusright;
                _label.ForeColor = _focuscaption;
                _input.ForeColor = Locked ? _label.ForeColor : _focustext;
                // _middle.BackColor = _left.BackColor; // this.BackColor;
            }
            else
            {
                if (_statehover)
                {
                    this.BackColor = _hoverborder;
                    _left.BackColor = _hoverleft;
                    _left.ForeColor = _hovercaption;
                    _right.BackColor = _hoverright;
                    _label.ForeColor = _hovercaption;
                    _input.ForeColor = Locked ? _label.ForeColor : _hovertext;
                    // _middle.BackColor = _left.BackColor;
                }
                else
                {
                    this.BackColor = _normalborder;
                    _left.BackColor = _normalleft;
                    _left.ForeColor = _normalcaption;
                    _right.BackColor = _normalright;
                    _label.ForeColor = _normalcaption;
                    _input.ForeColor = Locked ? _label.ForeColor : _normaltext;
                    // _middle.BackColor = _left.BackColor;
                }
            }
            _input.BackColor = _right.BackColor;
        }

        #endregion

        #region accessor

        /// <summary></summary>
        public event EventHandler Changed;

        /// <summary>添加选项。</summary>
        /// <param name="value"></param>
        public void Add(string value)
        {
            Add(value, value);
        }

        /// <summary>添加选项。</summary>
        /// <param name="value"></param>
        /// <param name="alias"></param>
        public void Add(string value, string alias)
        {
            Add(value, alias, Color.Black);
        }

        /// <summary>添加选项。</summary>
        /// <param name="value"></param>
        /// <param name="alias"></param>
        /// <param name="color"></param>
        public void Add(string value, string alias, Color color)
        {
            if (value != null)
            {
                var v = value;
                var a = string.IsNullOrEmpty(alias) ? v : alias;
                var c = (color == null) ? Color.Black : color;
                _value.Add(v);
                _alias.Add(a);
                _color.Add(c);

                _input.Items.Add(a);
            }
        }

        /// <summary>清除所有选项。</summary>
        public void Clean()
        {
            Clear();
        }

        /// <summary>清除所有选项。</summary>
        public void Clear()
        {
            _value.Clear();
            _alias.Clear();
            _color.Clear();
            _input.Items.Clear();
        }

        #endregion

        #region event

        private void EventInit()
        {
            this.Resize += Event_Main_Resize;
            this.MouseMove += Event_Caption_MouseMove;
            this.MouseLeave += Event_Caption_MouseLeave;
            this.MouseDown += Event_Caption_MouseDown;

            _left.MouseMove += Event_Caption_MouseMove;
            _left.MouseLeave += Event_Caption_MouseLeave;
            _left.MouseDown += Event_Caption_MouseDown;

            _right.MouseMove += Event_Caption_MouseMove;
            _right.MouseLeave += Event_Caption_MouseLeave;
            _right.MouseDown += Event_Caption_MouseDown;

            _label.MouseMove += Event_Caption_MouseMove;
            _label.MouseLeave += Event_Caption_MouseLeave;
            _label.MouseDown += Event_Caption_MouseDown;

            _input.MouseMove += Event_Caption_MouseMove;
            _input.MouseLeave += Event_Caption_MouseLeave;
            _input.GotFocus += Event_GotFocus;
            _input.LostFocus += Event_LostFocus;
            _input.TextChanged += Event_Input_TextChanged;
            _input.DrawItem += Event_Input_DrawItem;
            _input.SelectedIndexChanged += Event_Input_SelectedIndexChanged;
        }

        private void Event_Input_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Changed != null) Changed(this, new EventArgs());
        }

        private void Event_Input_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index < 0) return;
            e.DrawBackground();
            e.DrawFocusRectangle();
            var vs = _input.Items[e.Index].ToString();
            var vx = e.Bounds.X + 7;
            var vy = e.Bounds.Y + 1; // e.Bounds.Y + (_input.ItemHeight - 16) / 2;
            var vb = new SolidBrush(e.ForeColor);
            if (_color != null)
            {
                if (e.Index < _color.Count)
                {
                    vb.Dispose();
                    vb = new SolidBrush(_color[e.Index]);
                }
            }
            e.Graphics.DrawString(vs, FormsUtility.DefaultFont, vb, vx, vy);
            vb.Dispose();
        }

        private void Event_Input_TextChanged(object sender, EventArgs e)
        {
            if ((Changed != null) && (!Locked)) Changed(this, new EventArgs());
        }

        private void Event_LostFocus(object sender, EventArgs e)
        {
            _statefocus = false; GoColor();
        }

        private void Event_GotFocus(object sender, EventArgs e)
        {
            _statefocus = true; GoColor();
        }

        private void Event_Caption_MouseMove(object sender, MouseEventArgs e)
        {

        }

        private void Event_Caption_MouseDown(object sender, MouseEventArgs e)
        {
            _input.Focus();
        }

        private void Event_Main_Resize(object sender, EventArgs e)
        {
            ControlAdjust();
        }

        private void Event_Caption_MouseLeave(object sender, EventArgs e)
        {
            _statehover = false; GoColor();
        }

        private void Event_caption_mousemove(object sender, MouseEventArgs e)
        {
            _statehover = true; GoColor();
        }

        #endregion

        #region property

        /// <summary>标签文本。</summary>
        public string Caption
        {
            get { return _label.Text; }
            set { _label.Text = string.IsNullOrEmpty(value) ? "" : value; }
        }

        /// <summary>内容文本。</summary>
        public new string Text
        {
            get { return _input.Text; }
            set { _input.Text = string.IsNullOrEmpty(value) ? "" : value; }
        }

        /// <summary>内容文本最大长度。</summary>
        public int Capacity
        {
            get { return _input.MaxLength; }
            set { _input.MaxLength = (value < 0) ? 0 : value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public float FontSize
        {
            get { return _input.Font.Size; }
            set { _input.Font = new Font(FormsUtility.DefaultFontName, value); }
        }

        /// <summary>独立控件，不接受 Tab 键事件。</summary>
        public bool Lonely
        {
            get { return !_input.TabStop; } // return _lonely; }
            set { _input.TabStop = !value; } //            _lonely = value; _input.AcceptsTab = !value; }
        }

        /// <summary>锁定内容，禁止编辑。</summary>
        public override bool Locked
        {
            get { return !_input.Enabled; }
            set { _input.Enabled = !value; GoColor(); }
        }

        /// <summary>能够直接输入内容。</summary>
        public bool CanInput
        {
            get { return (_input.DropDownStyle == ComboBoxStyle.DropDown); }
            set { _input.DropDownStyle = value ? ComboBoxStyle.DropDown : ComboBoxStyle.DropDownList; }
        }

        /// <summary>内容为空。</summary>
        public bool IsEmpty
        {
            get { return string.IsNullOrEmpty(_input.Text); }
        }

        /// <summary></summary>
        public int MenuCount
        {
            get { return _input.MaxDropDownItems; }
            set { _input.MaxDropDownItems = (value > 0) ? value : 1; }
        }

        #endregion

        #region color

        private Color _normalborder = FormsUtility.GraceBorder;
        private Color _normalleft = FormsUtility.White;
        private Color _normalright = FormsUtility.White;
        private Color _normalcaption = FormsUtility.GraceLocked;
        private Color _normaltext = FormsUtility.Black;

        private Color _hoverborder = FormsUtility.GraceSilver;
        private Color _hoverleft = FormsUtility.White;
        private Color _hoverright = FormsUtility.White;
        private Color _hovercaption = FormsUtility.GraceLocked;
        private Color _hovertext = FormsUtility.Black;

        private Color _focusborder = FormsUtility.GraceSilver; // FormsUtility.silver;
        private Color _focusleft = FormsUtility.White; // FormsUtility.wall;
        private Color _focusright = FormsUtility.White;
        private Color _focuscaption = FormsUtility.GraceMinor; // FormsUtility.gray;
        private Color _focustext = FormsUtility.Black;

        /// <summary></summary>
        public Color NormalBorder { get { return _normalborder; } set { if (value != null) _normalborder = value; GoColor(); } }

        /// <summary></summary>
        public Color NormalLeft { get { return _normalleft; } set { if (value != null) _normalleft = value; GoColor(); } }

        /// <summary></summary>
        public Color NormalRight { get { return _normalright; } set { if (value != null) _normalright = value; GoColor(); } }

        /// <summary></summary>
        public Color NormalCaption { get { return _normalcaption; } set { if (value != null) _normalcaption = value; GoColor(); } }

        /// <summary></summary>
        public Color NormalText { get { return _normaltext; } set { if (value != null) _normaltext = value; GoColor(); } }

        /// <summary></summary>
        public Color HoverBorder { get { return _hoverborder; } set { if (value != null) _hoverborder = value; GoColor(); } }

        /// <summary></summary>
        public Color HoverLeft { get { return _hoverleft; } set { if (value != null) _hoverleft = value; GoColor(); } }

        /// <summary></summary>
        public Color HoverRight { get { return _hoverright; } set { if (value != null) _hoverright = value; GoColor(); } }

        /// <summary></summary>
        public Color HoverCaption { get { return _hovercaption; } set { if (value != null) _hovercaption = value; GoColor(); } }

        /// <summary></summary>
        public Color HoverText { get { return _hovertext; } set { if (value != null) _hovertext = value; GoColor(); } }

        /// <summary></summary>
        public Color FocusBorder { get { return _focusborder; } set { if (value != null) _focusborder = value; GoColor(); } }

        /// <summary></summary>
        public Color FocusLeft { get { return _focusleft; } set { if (value != null) _focusleft = value; GoColor(); } }

        /// <summary></summary>
        public Color FocusRight { get { return _focusright; } set { if (value != null) _focusright = value; GoColor(); } }

        /// <summary></summary>
        public Color FocusCaption { get { return _focuscaption; } set { if (value != null) _focuscaption = value; GoColor(); } }

        /// <summary></summary>
        public Color FocusText { get { return _focustext; } set { if (value != null) _focustext = value; GoColor(); } }

        #endregion

    }

}

#endif
